#! /usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2011 BidiX (http://bidix.info)
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
#
"""
	defined markdown extensions :
		DelExtension
		HilitedExtension
"""
import re
import markdown
from markdown.inlinepatterns import Pattern
"""
	DelExtension
	
	--Text deleted-- is converted to <del>Text deleted</del>
	
"""

DEL_RE = r'(--)(.*?)--'

class DelExtension(markdown.Extension):
	def extendMarkdown(self, md, md_globals):
		del_tag = markdown.inlinepatterns.SimpleTagPattern(DEL_RE, 'del')
		md.inlinePatterns.add('del', del_tag, '>not_strong')

"""
	HilitedExtension
	!!text hilited!! is converted to <span class="hilited">text hilited</span> 
"""
HILITED_RE = r'(!!)(.*?)!!'

class SpanPattern (Pattern):
	"""
	Return element of type `span` with a class `cls` with a text attribute of group(3)
	of a Pattern.

	"""
	def __init__ (self, pattern, cls):
		Pattern.__init__(self, pattern)
		self.cls = cls

	def handleMatch(self, m):
		el = markdown.etree.Element('span')
		el.set('class', self.cls)
		el.text = m.group(3)
		return el



class HilitedExtension(markdown.Extension):
	def extendMarkdown(self, md, md_globals):
		hilited_tag = SpanPattern(HILITED_RE, 'hilited')
		md.inlinePatterns.add('hilited', hilited_tag, '>not_strong')
	
"""
	InlineExtension
	convert characters to a symbol
		->	→
		=>	⇒
		<-	←
		<=	⇐
		(c)	©
		(r)	®
		...	…
		<<	«
		>>	»
		(>)	▶
		(v)	▼

"""

LEFT_ARROW_PATTERN_RE = r'->'
LEFT_DOUBLE_ARROW_PATTERN_RE = r'=>'
RIGHT_ARROW_PATTERN_RE = r'<-'
RIGHT_DOUBLE_ARROW_PATTERN_RE = r'<='
COPYRIGHT_RE = r'\(c\)'
REGISTRED_RE = r'\(r\)'
HELLIP_RE = r'\.\.\.'
RAQUO_RE = r'>>'
LAQUO_RE = r'<<'
LEFT_TRIANGLE_RE = r'\(>\)'
DOWN_TRIANGLE_RE = r'\(v\)'

class SimpleTextPattern (Pattern):
	""" Return a simple text of group(2) of a Pattern. """
	def __init__ (self, pattern, replace):
		Pattern.__init__(self, pattern)
		self.replace = replace

	def handleMatch(self, m):
		return self.replace

class InlineExtension(markdown.Extension):
	def extendMarkdown(self, md, md_globals):
		md.inlinePatterns["left_arrow"] = \
			SimpleTextPattern(LEFT_ARROW_PATTERN_RE, u'→')
		md.inlinePatterns["left_double_arrow"] = \
			SimpleTextPattern(LEFT_DOUBLE_ARROW_PATTERN_RE, u'⇒')
		md.inlinePatterns["right_arrow"] = \
			SimpleTextPattern(RIGHT_ARROW_PATTERN_RE, u'←')
		md.inlinePatterns["right_double_arrow"] = \
			SimpleTextPattern(RIGHT_DOUBLE_ARROW_PATTERN_RE, u'⇐')
		md.inlinePatterns["copyright"] = \
			SimpleTextPattern(COPYRIGHT_RE, u'©')
		md.inlinePatterns["registred"] = \
			SimpleTextPattern(REGISTRED_RE, u'®')
		md.inlinePatterns["hellip"] = \
			SimpleTextPattern(HELLIP_RE, u'…')
		md.inlinePatterns["raquo"] = \
			SimpleTextPattern(RAQUO_RE, u'»')
		md.inlinePatterns["laquo"] = \
			SimpleTextPattern(LAQUO_RE, u'«')
		md.inlinePatterns["left_triangle"] = \
			SimpleTextPattern(LEFT_TRIANGLE_RE, u'\u25B6')
		md.inlinePatterns["down_triangle"] = \
			SimpleTextPattern(DOWN_TRIANGLE_RE, u'\u25BC')


'''
	WikiLinkExtension
	
	Based on WikiLinks extension to Markdown
	http://www.freewisdom.org/projects/python-markdown/WikiLinks
	
	added :
	  - a 'buil_text' callback for displaying the text of the link
	  - an missing_html_class uses as class in the link if the build_text return exists=False
	  - a context object to pass global context
	
'''
def element_builder(label, base_url, end_url, context):
	""" Build an 'a' element from the label, a base_url, an end_url and a context
		return url, text, title and url_exists
	"""
	clean_label = re.sub(r'([ ]+_)|(_[ ]+)|([ ]+)', '_', label)
	url = '%s%s%s'% (base_url, clean_label, end_url)
	text = label
	title = clean_label
	url_exists = False
	return (url, text, title, url_exists)


class WikiLinkExtension(markdown.Extension):
	def __init__(self, configs):
		# set extension defaults
		self.config = {
						'base_url' : ['/', 'String to append to beginning or URL.'],
						'end_url' : ['/', 'String to append to end of URL.'],
						'html_class' : ['wikilink', 'CSS hook. Leave blank for none.'],
						'missing_html_class' : ['missing-wikilink', 'CSS hook. Leave blank for none.'],
						'element_builder' : [element_builder, 'Callable formats URL from label.'],
 						'context' : [None, 'Global context available for building labal.'],
		}
		
		# Override defaults with user settings
		for key, value in configs :
			self.setConfig(key, value)
		
	def extendMarkdown(self, md, md_globals):
		self.md = md
	
		# append to end of inline patterns
		# added '/' in wikilink 
		WIKILINK_RE = r'\[\[([A-Za-z0-9_ -/]+)\]\]'
		wikilinkPattern = WikiLink(WIKILINK_RE, self.config)
		wikilinkPattern.md = md
		md.inlinePatterns.add('wikilink2', wikilinkPattern, "<not_strong")


class WikiLink(markdown.inlinepatterns.Pattern):
	def __init__(self, pattern, config):
		markdown.inlinepatterns.Pattern.__init__(self, pattern)
		self.config = config
		
	def handleMatch(self, m):
		if m.group(2).strip():
			base_url, end_url, html_class, missing_html_class, context = self._getMeta()
			label = m.group(2).strip()
			url, text, title, url_exists = self.config['element_builder'][0](label, base_url, end_url, context)
			a = markdown.etree.Element('a')
			a.set('href', url)
			a.text = text
			a.set('title', title)
			if url_exists and html_class:
				a.set('class', html_class)
			elif not url_exists and missing_html_class:
				a.set('class', missing_html_class)
		else:
			a = ''
		return a

	def _getMeta(self):
		""" Return meta data or config data. """
		base_url = self.config['base_url'][0]
		end_url = self.config['end_url'][0]
		html_class = self.config['html_class'][0]
		missing_html_class = self.config['missing_html_class'][0]
		context = self.config['context'][0]
		if hasattr(self.md, 'Meta'):
			if self.md.Meta.has_key('wiki_base_url'):
				base_url = self.md.Meta['wiki_base_url'][0]
			if self.md.Meta.has_key('wiki_end_url'):
				end_url = self.md.Meta['wiki_end_url'][0]
			if self.md.Meta.has_key('wiki_html_class'):
				html_class = self.md.Meta['wiki_html_class'][0]
			if self.md.Meta.has_key('wiki_missing_html_class'):
				html_class = self.md.Meta['wiki_missing_html_class'][0]
			if self.md.Meta.has_key('context'):
				context = self.md.Meta['context'][0]
		return base_url, end_url, html_class, missing_html_class, context
	
